package com.up.vms.interfaces.rest.utils;

import org.apache.commons.lang3.StringUtils;

import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.*;

public class ParamUtil {

    private ParamUtil() {
    }

    private static final String UTF_8 = "utf-8";

    /**
     * 方法用途: 对所有传入参数按照字段名的 ASCII 码从小到大排序（字典序），并且生成url参数串<br>
     * 空值字符串未加入 用于生成签名<br>
     *
     * @param paraMap
     *             要排序的Map对象
     * @param urlEncode
     *             是否需要URLEncode
     * @param keyToLower
     *             是否需要将Key转换为全小写 true:key转化成小写，false:不转化
     * @return
     * @throws UnsupportedEncodingException
     */
    public static String formatUrlMap(Map<String, String> paraMap, boolean urlEncode, boolean keyToLower)
            throws UnsupportedEncodingException {
        String buff;
        Map<String, String> tmpMap = paraMap;
        List<Map.Entry<String, String>> infoIds = new ArrayList<>(tmpMap.entrySet());
        // 对所有传入参数按照字段名的 ASCII 码从小到大排序（字典序）
        Collections.sort(infoIds, Comparator.comparing(Map.Entry<String, String>::getKey));
        // 构造URL 键值对的格式
        StringBuilder buf = new StringBuilder();
        for (Map.Entry<String, String> item : infoIds) {
            if (StringUtils.isNotBlank(item.getKey())) {
                String key = item.getKey();
                String val = item.getValue();
                if (!"".equals(val)) {
                    if (urlEncode) {
                        val = URLEncoder.encode(val, UTF_8);
                    }
                    if (keyToLower) {
                        buf.append(key.toLowerCase() + "=" + val);
                    } else {
                        buf.append(key + "=" + val);
                    }
                    buf.append("&");
                }
            }

        }
        buff = buf.toString();
        if (!buff.isEmpty()) {
            buff = buff.substring(0, buff.length() - 1);
        }
        return buff;
    }

    /**
     * 按接口要求排序拼接字符串
     *
     * @param paraMap
     * @param urlEncode
     * @param keyToLower
     * @return
     * @throws UnsupportedEncodingException
     */
    public static String format2Str(Map<String, String> paraMap, boolean urlEncode, boolean keyToLower)
            throws UnsupportedEncodingException {
        String buff = "";
        Map<String, String> tmpMap = paraMap;
        List<Map.Entry<String, String>> infoIds = new ArrayList<>(tmpMap.entrySet());
        // 对所有传入参数按照字段名的 ASCII 码从小到大排序（字典序）
        Collections.sort(infoIds, Comparator.comparing(Map.Entry<String, String>::getKey));

        // 构造URL 键值对的格式
        StringBuilder buf = new StringBuilder();
        for (Map.Entry<String, String> item : infoIds) {
            if (StringUtils.isNotBlank(item.getKey())) {
                String key = item.getKey();
                String val = item.getValue();
                if (val !=null && !"".equals(val)) {
                    if (keyToLower) {
                        buf.append(key.toLowerCase() + val);
                    } else {
                        buf.append(key + val);
                    }
                }
            }

        }
        buff = buf.toString();
        if (urlEncode) {
            buff = URLEncoder.encode(buff, UTF_8);
        }

        return buff;
    }

    /**
     * 将map转换成url param串
     * @param map
     * @param urlEncode
     * @return
     * @throws UnsupportedEncodingException
     */
    public static String formatUrlParam(Map<String, String> map, boolean urlEncode)
            throws UnsupportedEncodingException {
        if (map == null) {
            return "";
        }
        StringBuffer sb = new StringBuffer();
        for (Map.Entry<String, String> entry : map.entrySet()) {
            String key = entry.getKey();
            String val = entry.getValue();
            if (val == null) {
                val = "";
            }
            if (urlEncode) {
                val = URLEncoder.encode(val, UTF_8);
            }
            sb.append(key + "=" + val);
            sb.append("&");
        }
        String s = sb.toString();
        if (s.endsWith("&")) {
            s = StringUtils.substringBeforeLast(s, "&");
        }
        return s;
    }
}
